package com.dl.study.module.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.dl.study.config.jwt.JwtUtil;
import com.dl.study.config.jwt.ShiroKit;
import com.dl.study.config.propertites.JwtProperties;
import com.dl.study.config.redis.RedisConstant;
import com.dl.study.config.redis.RedisUtil;
import com.dl.study.module.user.dao.UserDao;
import com.dl.study.module.user.domain.dto.UserLoginDTO;
import com.dl.study.module.user.domain.dto.UserQueryListDto;
import com.dl.study.module.user.domain.entity.UserEntity;
import com.dl.study.module.user.service.UserService;
import com.dl.study.util.BeanCopyUtil;
import com.dl.study.util.resp.LoginResponseCodeConst;
import com.dl.study.util.resp.ResponseCodeConst;
import com.dl.study.util.resp.ResponseDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.List;

/**
 * @Author: user
 * @Date: 2021/8/30 21:30
 * @Description:
 */
@Service
@EnableConfigurationProperties({JwtProperties.class})
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RedisUtil redis;

    @Autowired
    private JwtProperties jwtProperties;


    @Override
    public ResponseDTO<Object> create(String serile) {
        int result = userDao.create(serile);
        return ResponseDTO.succ();
    }

    @Override
    public ResponseDTO<Object> add(UserQueryListDto userQueryListDto) {
        UserEntity userEntity = BeanCopyUtil.copy(userQueryListDto, UserEntity.class);
        int result = userDao.insert(userEntity);
        return ResponseDTO.succMsg("添加成功");
    }

    @Override
    public ResponseDTO<Object> login(UserLoginDTO userLoginDTO, HttpServletResponse response) {
        Assert.notNull(userLoginDTO.getLoginName(), "登录名不能为空");
        Assert.notNull(userLoginDTO.getLoginPwd(), "密码不能为空");
        /*List<UserEntity> list= userDao.getByLoginName(userLoginDTO.getLoginName());
        if(CollectionUtils.isEmpty(list)){
            return  ResponseDTO.wrap(LoginResponseCodeConst.USER_ERROR_EXIST);
        }
        UserEntity userBean=list.get(0);
        String encodePassword = ShiroKit.md5(userLoginDTO.getLoginPwd(), RedisConstant.LOGIN_SALT);
        if (!encodePassword.equals(userBean.getLoginPwd())) {
            return ResponseDTO.wrap(LoginResponseCodeConst.LOGIN_ERROR_PARAM);
        }*/

        //账号是否锁定
       /* if ("0".equals(userBean.getStatus())) {
            return ResponseDTO.wrap(LoginResponseCodeConst.USER_STATUS_ERROR_TOKEN);
        }*/

        ///验证成功后处理
        String token = this.loginSuccess(userLoginDTO.getLoginName(), response);

        //登录成功
        return ResponseDTO.succData(token, "登录成功");

    }

    @Override
    public ResponseDTO<Object> logout(HttpServletRequest request) {
        try {
            String token = "";
            // 获取头部信息
            Enumeration<String> headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = headerNames.nextElement();
                String value = request.getHeader(key);
                if ("Authorization".equalsIgnoreCase(key)) {
                    token = value;
                }
            }
            // 校验token
            if (StringUtils.isBlank(token)) {
                return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM);
            }
            String account = JwtUtil.getClaim(token, RedisConstant.ACCOUNT);
            if (StringUtils.isBlank(account)) {
                return ResponseDTO.wrap(ResponseCodeConst.TOKEN_ERROR);
            }
            // 清除shiro权限信息缓存
            if (redis.hasKey(RedisConstant.PREFIX_SHIRO_CACHE + account)) {
                redis.del(RedisConstant.PREFIX_SHIRO_CACHE + account);
            }
            // 清除RefreshToken
            redis.del(RedisConstant.PREFIX_SHIRO_REFRESH_TOKEN + account);

            return ResponseDTO.succ();
        } catch (Exception e) {
            return ResponseDTO.systemError(e.getMessage());
        }
    }


    /**
     * 登录后更新缓存，生成token，设置响应头部信息
     *
     * @param account
     * @param response
     */
    private String loginSuccess(String account, HttpServletResponse response) {

        String currentTimeMillis = String.valueOf(System.currentTimeMillis());

        // 清除可能存在的Shiro权限信息缓存
        String tokenKey = RedisConstant.PREFIX_SHIRO_CACHE + account;
        if (redis.hasKey(tokenKey)) {
            redis.del(tokenKey);
        }

        //更新RefreshToken缓存的时间戳
        String refreshTokenKey = RedisConstant.PREFIX_SHIRO_REFRESH_TOKEN + account;
//        if (redis.hasKey(refreshTokenKey)) {
        redis.set(refreshTokenKey, currentTimeMillis, jwtProperties.getRefreshTokenExpireTime() * 60 * 60L);
//        }else{
//            redis.set(refreshTokenKey, currentTimeMillis, jwtProperties.getRefreshTokenExpireTime()*60*60L);
//        }

        //生成token
        JSONObject json = new JSONObject();
        String token = JwtUtil.sign(account, currentTimeMillis);
        json.put("token", token);

        //写入header
        response.setHeader(RedisConstant.REQUEST_AUTH_HEADER, token);
        // response.setHeader(RedisConstant.REQUEST_TOKEN_HEADER, token);
        response.setHeader("Access-Control-Expose-Headers", RedisConstant.REQUEST_AUTH_HEADER);
        return token;
    }


}
